﻿using Net.Event;
using System;
using System.IO;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WebSocketSharp.Server;

namespace HttpFileServer
{
    public partial class Form1 : Form
    {
        private Data hfsData;
        private HttpServer server;

        public Form1(string path)
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            hfsData = Net.Helper.PersistHelper.Deserialize("hfs.json", new Data(), true);
            if (!string.IsNullOrEmpty(path))
                hfsData.DocumentRootPath = path;
            hfsData.Url = $"http://{GetIPAddress()}:8080/";
            textBox1.Text = hfsData.Url;
            textBox2.Text = hfsData.DocumentRootPath;
            textBox3.Text = hfsData.SpeedLimit.ToString();
            textBox2.AllowDrop = true;
            textBox2.DragEnter += ListBox1_DragEnter;
            textBox2.DragDrop += ListBox1_DragDrop;
            NDebug.BindLogAll(msg =>
            {
                listBox2.Items.Add(msg);
            });
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void OnHeadHandler(object sender, HttpRequestEventArgs e)
        {
            var req = e.Request;
            var res = e.Response;
            var path = req.RawUrl;
            if (!e.TryReadFile(path, out var contents))
            {
                res.StatusCode = (int)HttpStatusCode.NotFound;
                res.Close();
                return;
            }
            res.StatusCode = (int)HttpStatusCode.OK;
            res.ContentType = "application/octet-stream";
            res.ContentLength64 = contents.Length;
            //res.OutputStream.Write(contents, 0, contents.Length);
            res.Close(contents, true);
            listBox2.Items.Add($"获取数据头:{path}");
        }

        private async void OnGetHandler(object sender, HttpRequestEventArgs e)
        {
            var req = e.Request;
            var res = e.Response;
            var path = req.RawUrl;
            if (!e.TryReadFile(path, out var fileBytes))
            {
                res.StatusCode = (int)HttpStatusCode.NotFound;
                res.Close();
                return;
            }
            res.ContentType = "application/octet-stream";
            res.ContentLength64 = fileBytes.Length;
            if (hfsData.SpeedLimit > 0)
            {
                res.SendChunked = true;
                try
                {
                    var totalBytesSent = 0;
                    while (totalBytesSent < fileBytes.Length)
                    {
                        var SpeedLimit = (1024 / 10) * (hfsData.SpeedLimit <= 0 ? 1 : hfsData.SpeedLimit);
                        var bytesToSend = Math.Min(SpeedLimit, fileBytes.Length - totalBytesSent);
                        res.OutputStream.Write(fileBytes, totalBytesSent, bytesToSend);
                        totalBytesSent += bytesToSend;
                        res.OutputStream.Flush();
                        await Task.Delay(100);
                    }
                    res.Close();
                }
                catch (Exception)
                {
                    listBox2.Items.Add($"取消下载文件:{path}");
                    return;
                }
            }
            else
            {
                res.OutputStream.Write(fileBytes, 0, fileBytes.Length);
                res.Close();
            }
            listBox2.Items.Add($"下载文件:{path}");
        }

        private string GetIPAddress()
        {
            //var hostName = Dns.GetHostName();
            //var iPHostEntry = Dns.GetHostEntry(hostName);
            //var ipAddress = IPAddress.Any;
            //foreach (var ipAdd in iPHostEntry.AddressList)
            //    if (ipAdd.AddressFamily == AddressFamily.InterNetwork)
            //        ipAddress = ipAdd;
            //return ipAddress.ToString();

            var physicalAdapters = NetworkInterface.GetAllNetworkInterfaces()
                .Where(n => n.OperationalStatus == OperationalStatus.Up) // 仅启用状态 
                .Where(n => !IsVirtualAdapter(n)) // 过滤虚拟适配器 
                .ToList();

            foreach (var adapter in physicalAdapters)
            {
                var ipProps = adapter.GetIPProperties();
                foreach (var ip in ipProps.UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        return ip.Address.ToString();
                }
            }
            return string.Empty;
        }

        private static bool IsVirtualAdapter(NetworkInterface adapter)
        {
            string lowerDesc = adapter.Description.ToLower();
            string lowerName = adapter.Name.ToLower();

            // 常见虚拟适配器关键词（可根据需要扩展）
            return lowerDesc.Contains("virtual") ||
                   lowerDesc.Contains("vmware") ||
                   lowerDesc.Contains("hyper-v") ||
                   lowerName.Contains("vpn") ||
                   lowerName.Contains("virtual");
        }

        private void ListBox1_DragEnter(object sender, DragEventArgs e)
        {
            // 检查拖入的内容是否为文件夹
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (files.Length > 0 && Directory.Exists(files[0]))
                {
                    e.Effect = DragDropEffects.Copy; // 设置拖放效果
                }
                else
                {
                    e.Effect = DragDropEffects.None; // 不允许拖放
                }
            }
            else
            {
                e.Effect = DragDropEffects.None; // 不允许拖放
            }
        }

        private void ListBox1_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files.Length > 0 && Directory.Exists(files[0]))
            {
                textBox2.Text = files[0];
                hfsData.DocumentRootPath = files[0];
                Net.Helper.PersistHelper.Serialize(hfsData, "hfs.json");
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            server?.Stop();
            server = new HttpServer(hfsData.Url);
            server.OnGet += OnGetHandler;
            server.OnHead += OnHeadHandler;
            server.DocumentRootPath = hfsData.DocumentRootPath;
            server.Start();
            button1.Text = "运行中";
            NDebug.Log("服务器运行成功!");
        }

        private void textBox1_TextChanged_1(object sender, EventArgs e)
        {
            hfsData.Url = textBox1.Text;
            Net.Helper.PersistHelper.Serialize(hfsData, "hfs.json");
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            int.TryParse(textBox3.Text, out int value);
            hfsData.SpeedLimit = value;
            Net.Helper.PersistHelper.Serialize(hfsData, "hfs.json");
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            hfsData.DocumentRootPath = textBox2.Text;
            Net.Helper.PersistHelper.Serialize(hfsData, "hfs.json");
        }
    }
}